<?php
namespace app\client\controller;
use app\client\lib\Redis;
use think\swoole\facade\Task;
use app\common\lib\GatewayCurl;

class Settlement {
    public function charge() {
        $params = request()->post();
        $sim = isset($params['sim']) ? trim($params['sim']) : '';
        $portNo = isset($params['port_no']) ? intval($params['port_no']) : 0;
        $deviceId = !empty($params['device_id']) ? intval($params['device_id']) : -1;
        $orderId = !empty($params['order_id']) ? intval($params['order_id']) : 0;
        if($sim === '' || $portNo <= 0 || $deviceId < 0 || $orderId < 0) {
            return errorResult();
        }
        
        $deviceModel = model('Device');
        if(empty($deviceId)) {
            $deviceId = $deviceModel->where(['sim_iccid' => $sim])->value('device_id');
            if(empty($deviceId)) {
                return errorResult('b');
            }
        }
        
        if(empty($orderId)) {
            try {
                $redis = new Redis();
                $orderId = $redis->get($sim . ':' . $portNo);
                $redis->close();
            } catch (\Exception $e) {
            }
            
            if(empty($orderId)) {
                $orderId = model('DevicePort')->where(['device_id' => $deviceId, 'port_no' => $portNo])->value('current_order_id');
                if(empty($orderId)){
                    return errorResult('c');
                }
            }
        }

        $time = time();
        $usedTime = $params['consume_time']; //充电时长
        $consumeEnergy = roundNumber($params['consume_energy'] / 1000, 3); //充电量
        $power = $params['avg_power']; //平均功率
        $maxPower = $params['max_power']; //最大功率
        $stopReason = $params['stop_reason']; //停止原因
        
        $orderModel = model('ChargeOrder');
        $orderModel->startTrans();
        try {
            $order = $orderModel->where(['order_id' => $orderId])->field('user_id, order_no, device_no, status, amount, charge_quantity, agent_id, store_id, profit_rate, charge_type, charge_unit, pay_to')->lock(true)->find();;
            if(empty($order)){
                $orderModel->rollback();
                return errorResult('d');
            }
            
            if($order['status'] != 1){
                $orderModel->rollback();
                return errorResult('e');
            }
            
            $openId = model('User')->where(['user_id' => $order['user_id']])->value('openid');
            
            $orderNo = $order['order_no'];
            $deviceNo = $order['device_no'];
            $chargeUnit = $order['charge_unit'];
            $settlmentQuantity = 0;
            
            if($order['charge_type'] == 1){ //计时
                if($usedTime <= 1) {
                    $settlmentQuantity = 0;
                }else{
                    if($chargeUnit == 0) { //不退费
                        $settlmentQuantity = $order['charge_quantity'];
                    }else {
                        $offset = ceil($usedTime / $chargeUnit); //剩余的时间
                        $settlmentQuantity = $offset - $chargeUnit;
                    }
                }
                
            }else{ //计量
                if($consumeEnergy > 0) {
                    if($chargeUnit == 0) { //不退费
                        $settlmentQuantity = $order['charge_quantity'];
                    }else {
                        $offset = ceil($consumeEnergy / $chargeUnit);
                        $settlmentQuantity = $offset - $chargeUnit;
                    }
                }
                
            }
            
            if($settlmentQuantity >= $order['charge_quantity']){
                $settlmentQuantity = $order['charge_quantity'];
            }
            
            $consumeAmount = round(($order['amount'] / $order['charge_quantity']) * $settlmentQuantity, 2);
            $refundAmount = roundNumber($order['amount'] - $consumeAmount, 2);
            
            //更新订单
            $rs = $orderModel->modify(['order_id' => $orderId], ['consume_amount' => $consumeAmount, 'consume_time' => $usedTime, 'consume_energy' => $consumeEnergy, 'max_power' => $maxPower, 'avg_power' => $power, 'stop_reason' => $stopReason, 'status' => 2, 'end_time' => $time]);
            if(!$rs){
                $orderModel->rollback();
                return errorResult('f');
            }
            
            if($consumeAmount > 0) { //有利润
                $device = $deviceModel->where(['device_id' => $deviceId])->field(['online_amount'])->lock(true)->find();
                $rs = $deviceModel->modify(['device_id' => $deviceId], ['online_amount' => $device['online_amount'] + $consumeAmount]);
                if(!$rs){
                    $orderModel->rollback();
                    return errorResult('g');
                }
                
                if($order['agent_id'] > 0){
                    $storeAmount = roundNumber($consumeAmount * $order['profit_rate'] / 100, 2);
                    $agentAmount = $consumeAmount - $storeAmount;
                    
                    
                    $agentModel = model('Agent');
                    $agent = $agentModel->where(['agent_id' => $order['agent_id']])->field('total_amount, profit_amount, profit_online_amount, amount')->lock(true)->find();
                    
                    if(!empty($agent)){
                        $agentUpdate = [
                            'total_amount' => $consumeAmount + $agent['total_amount']
                        ];
                        
                        if($agentAmount > 0){
                            $agentUpdate['profit_amount'] = $agentAmount + $agent['profit_amount'];
                            $agentUpdate['profit_online_amount'] = $agentAmount + $agent['profit_online_amount'];
                            if($order['pay_to'] == 1){
                                $agentUpdate['amount'] = $agentAmount + $agent['amount'];
                            }
                            
                            $rs = model('AgentFinanceLog')->add(['agent_id' => $order['agent_id'], 'related_id' => $orderId, 'type' => 1, 'amount' => $agentAmount, 'add_time' => $time]);
                            if(!$rs){
                                $orderModel->rollback();
                                return errorResult('l');
                            }
                        }
                        
                        $rs = $agentModel->modify(['agent_id' => $order['agent_id']], $agentUpdate);
                        if(!$rs){
                            $orderModel->rollback();
                            return errorResult('h');
                        }
                    }
                    
                    if($order['store_id'] > 0 && $storeAmount > 0){
                        $storeModel = model('Store');
                        $store = $storeModel->where(['store_id' => $order['store_id']])->field('total_amount, profit_amount, profit_online_amount, amount')->lock(true)->find();
                        
                        if(!empty($store)){
                            $storeUpdate = [
                                'total_amount' => $consumeAmount + $store['total_amount']
                            ];
                            
                            if($storeAmount > 0){
                                $storeUpdate['profit_amount'] = $storeAmount + $store['profit_amount'];
                                $storeUpdate['profit_online_amount'] = $storeAmount + $store['profit_online_amount'];
                                if($order['pay_to'] == 1){
                                    $storeUpdate['amount'] = $storeAmount + $store['amount'];
                                }
                                
                                
                                $rs = model('StoreFinanceLog')->add(['store_id' => $order['store_id'], 'related_id' => $orderId, 'type' => 1, 'amount' => $storeAmount, 'add_time' => $time]);
                                if(!$rs){
                                    $orderModel->rollback();
                                    return errorResult('j');
                                }
                            }
                            
                            $rs = $storeModel->modify(['store_id' => $order['store_id']], $storeUpdate);
                            if(!$rs){
                                $orderModel->rollback('k');
                                return errorResult();
                            }
                        }
                    }
                }
                
                $platformModel = model('Platform');
                
                $flatform = $platformModel->where(['id' => 1])->field('online_amount')->lock(true)->find();
                $rs = $platformModel->modify(['id' => 1], ['online_amount' => $flatform['online_amount'] + $consumeAmount]);
                if(!$rs){
                    $orderModel->rollback('z');
                    return errorResult();
                }
                
                $rs = model('PlatformFinanceLog')->add(['related_id' => $orderId, 'type' => 1, 'amount' => $consumeAmount, 'add_time' => $time]);
                if(!$rs){
                    $orderModel->rollback();
                    return errorResult('v');
                }
            }
            
            $chargeQuantity = $order['charge_quantity'];
            
            Task::async(function() use($refundAmount, $orderId, $openId, $orderNo, $deviceNo, $portNo, $chargeQuantity, $consumeAmount, $usedTime, $consumeEnergy, $power, $maxPower, $stopReason, $time){
                if($refundAmount > 0){
                    $ch = curl_init('http://127.0.0.1:8888/client/chargeRefund');
                    curl_setopt($ch,CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
                    curl_setopt($ch, CURLOPT_POST, true); //设置为POST方式
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['id' => $orderId, 'amount' => $refundAmount]));//POST数据
                    $rs = curl_exec($ch);
                    curl_close($ch);
                }
                
                /* $redis = new Redis();
                 $data = [
                 'openid' => $openId,
                 'order_no' => $orderNo,
                 'device_no' => $deviceNo,
                 'port_no' => $portNo,
                 'charge_quantity' => $chargeQuantity, //实际设置充电时间
                 'consume_amount' => $consumeAmount,  //实际消费金额
                 'consume_quantity' => $chargeTime,  //实际充电时间
                 'consume_energy' => $chargeVolume,  //实际消耗电量
                 'max_power' => $maxPower,  //最大功率
                 'avg_power' => $power,  //平均功率
                 'stop_reason' => $stopReason, //停止原因
                 'end_time' => $time
                 ];
                 $redis->lpush('charge_message_template', $data);
                 $redis->close(); */
            });
            
            $orderModel->commit();
            
            return successResult();
            
       } catch (\Exception $e) {
            return errorResult($e->getMessage());
      }
        
        
    }
    
    //线上卡充电
    public function onlineCardCharge() {
        $params = request()->post();
        //$params = json_decode('{"sim":"89860419151871534245","device_id":"901030","order_id":"1030","port_no":1,"card_no":"0ABC1BA7","charge_type":2,"charge_quantity":0,"consume_time":0,"consume_energy":9,"avg_power":450,"max_power":500,"stop_reason":-1}', true);
        
        $cardNo = isset($params['card_no']) ? trim($params['card_no']) : '';
        $sim = isset($params['sim']) ? trim($params['sim']) : '';
        $portNo = isset($params['port_no']) ? intval($params['port_no']) : 0;
        $deviceId = !empty($params['device_id']) ? intval($params['device_id']) : -1;
        $orderId = !empty($params['order_id']) ? intval($params['order_id']) : 0;
        if($cardNo === '' || $sim === '' || $portNo <= 0 || $deviceId < 0 || $orderId < 0) {
            return errorResult();
        }
        
        if($orderId == 0){
            try {
                $redis = new Redis();
                $orderId = $redis->get('online_card:' . $sim . ':' . $portNo);
                $redis->close();
            } catch (\Exception $e) {
            }
        }
        
        $data['consume_time'] = $params['consume_time']; //充电时长
        $data['consume_energy'] = roundNumber($params['consume_energy'] / 1000, 3); //充电量
        $data['avg_power'] = $params['avg_power']; //平均功率
        $data['max_power'] = $params['max_power']; //最大功率
        $data['stop_reason'] = $params['stop_reason']; //停止原因
        
        $deviceModel = model('Device');
        $cardModel = model('OnlineCard');
        $chargePriceModel = model('ChargePrice');
        $cardChargeOrderModel = model('CardChargeOrder');
        $agentModel = model('Agent');
        $storeModel = model('Store');
        $agentFinanceLogModel = model('AgentFinanceLog');
        $storeFinanceModel = model('StoreFinanceLog');
        $platformModel = model('Platform');
        $flatformFinanceLogModel = model('PlatformFinanceLog');
        $onlineCardConsumeLogModel = model('OnlineCardConsumeLog');
        
        Task::async(function() use(&$data, &$deviceId, &$sim, &$orderId, &$portNo, &$cardNo, &$deviceModel, &$cardModel, &$chargePriceModel, &$cardChargeOrderModel, &$agentModel, &$storeModel, &$agentFinanceLogModel, &$storeFinanceModel, &$platformModel, &$flatformFinanceLogModel, &$onlineCardConsumeLogModel) {
            $repData = ['code' => 0, 'success' => false, 'deviceId' => $sim, 'portNo' => $portNo, 'cardType' => 1, 'money' => 0, 'cardNo' => $cardNo, 'msg' => ''];
            $curl = new GatewayCurl();
            
            if($deviceId == 0){
                $deviceId = $deviceModel->where(['sim_iccid' => $sim])->value('device_id');
            }
            
            $card = $cardModel->findOne(['card_no' => $cardNo], ['amount', 'card_id', 'user_id']);
            if(empty($card)) {
                $repData['msg'] = '卡不存在';
                $curl->send('onlineCardCharge', $repData);
                return true;
            }
            
            $cardChargeOrderModel->startTrans();
            
            try {
                $field = ['pay_to', 'agent_id', 'store_id', 'profit_rate', 'charge_quantity', 'charge_unit', 'charge_type', 'amount', 'status'];
                if(empty($orderId)) {
                    array_push($field, 'order_id');
                    $order = $cardChargeOrderModel->where(['device_id' => $deviceId, 'port_no' => $portNo, 'card_no' => $cardNo])->field(['charge_quantity', 'charge_type', 'status', 'amount', 'order_id'])->order('order_id desc')->lock(true)->find();
                }else {
                    $order = $cardChargeOrderModel->where(['order_id' => $orderId])->field($field)->lock(true)->find();
                }
                if(empty($order)) {
                    $cardChargeOrderModel->rollback();
                    $repData['msg'] = '订单不存在';
                    $curl->send('onlineCardCharge', $repData);
                    return true;
                }
                if($order['status'] != 1) {
                    $cardChargeOrderModel->rollback();
                    $repData['msg'] = '订单已完成';
                    $curl->send('onlineCardCharge', $repData);
                    return true;
                }
                
                if($orderId == 0) {
                    $orderId = $order['order_id'];
                }
                
                $settlmentQuantity = 0;
                $chargeUnit = $order['charge_unit'];
                
                if($order['charge_type'] == 1){ //计时
                    if($data['consume_time'] <= 1) {
                        $settlmentQuantity = 0;
                    }else{
                        if($chargeUnit == 0) { //不退费
                            $settlmentQuantity = $order['charge_quantity'];
                        }else {
                            $offset = ceil($data['consume_time'] / $chargeUnit);
                            $settlmentQuantity = $offset * $chargeUnit;
                        }
                    }
                    
                }else{ //计量
                    if($data['consume_energy'] > 0) {
                        if($chargeUnit == 0) { //不退费
                            $settlmentQuantity = $order['charge_quantity'];
                        }else {
                            $offset = ceil($data['consume_energy'] / $chargeUnit);
                            $settlmentQuantity = $offset * $chargeUnit;
                        }
                        
                    }
                }
                
                if($settlmentQuantity >= $order['charge_quantity']){
                    $settlmentQuantity = $order['charge_quantity'];
                }

                $consumeAmount = round(($order['amount'] / $order['charge_quantity']) * $settlmentQuantity, 2);
                $refundAmount = roundNumber($order['amount'] - $consumeAmount, 2);
                $time = time();
                
                //更新订单
                $rs = $cardChargeOrderModel->modify(['order_id' => $orderId], ['consume_amount' => $consumeAmount, 'consume_time' => $data['consume_time'], 'consume_energy' => $data['consume_energy'], 'max_power' => $data['max_power'], 'avg_power' => $data['avg_power'], 'stop_reason' => $data['stop_reason'], 'status' => 2, 'end_time' => $time]);
                if(!$rs){
                    $cardChargeOrderModel->rollback();
                    $repData['msg'] = '更新订单失败';
                    $curl->send('onlineCardCharge', $repData);
                    return true;
                }
                
                if($refundAmount > 0) { //有退款
                    $card['amount'] = $card['amount'] + $refundAmount;
                    $rs = $cardModel->modify(['card_id' => $card['card_id']], ['amount' => $card['amount']]);
                    if(!$rs){
                        $cardChargeOrderModel->rollback();
                        $repData['msg'] = '退款失败';
                        $curl->send('onlineCardCharge', $repData);
                        return true;
                    }
                }
                
                
                if($consumeAmount > 0) { //有利润
                    $rs = $onlineCardConsumeLogModel->add(['user_id' => $card['user_id'], 'card_id' => $card['card_id'], 'card_no' => $cardNo, 'amount' => $consumeAmount, 'related_id' => $orderId, 'add_time' => $time]);
                    if(!$rs){
                        $cardChargeOrderModel->rollback();
                        $repData['msg'] = '退加入卡消费记录失败';
                        $curl->send('onlineCardCharge', $repData);
                        return true;
                    }
                    
                    $device = $deviceModel->where(['device_id' => $deviceId])->field(['online_card_amount'])->lock(true)->find();
                    $rs = $deviceModel->modify(['device_id' => $deviceId], ['online_card_amount' => $device['online_card_amount'] + $consumeAmount]);
                    if(!$rs){
                        $cardChargeOrderModel->rollback();
                        $repData['msg'] = '更新设备收入失败';
                        $curl->send('onlineCardCharge', $repData);
                        return true;
                    }
                    
                    if($order['agent_id'] > 0) {
                        $storeAmount = roundNumber($consumeAmount * $order['profit_rate'] / 100, 2);
                        $agentAmount = $consumeAmount - $storeAmount;
                        var_dump('代理商的利益:' . $agentAmount);
                        $agent = $agentModel->where(['agent_id' => $order['agent_id']])->field('total_amount, profit_amount, profit_online_card_amount, amount')->lock(true)->find();
                        
                        if(!empty($agent)){
                            $agentUpdate = [
                                'total_amount' => $consumeAmount + $agent['total_amount']
                            ];
                            
                            if($agentAmount > 0){
                                $agentUpdate['profit_amount'] = $agentAmount + $agent['profit_amount'];
                                $agentUpdate['profit_online_card_amount'] = $agentAmount + $agent['profit_online_card_amount'];
                                if($order['pay_to'] == 1){
                                    $agentUpdate['amount'] = $agentAmount + $agent['amount'];
                                }
                                
                                $rs = $agentFinanceLogModel->add(['agent_id' => $order['agent_id'], 'related_id' => $orderId, 'type' => 2, 'amount' => $agentAmount, 'add_time' => $time]);
                                if(!$rs){
                                    $cardChargeOrderModel->rollback();
                                    $repData['msg'] = '加入代理商收入记录失败';
                                    $curl->send('onlineCardCharge', $repData);
                                    return true;
                                }
                            }
                            
                            $rs = $agentModel->modify(['agent_id' => $order['agent_id']], $agentUpdate);
                            var_dump($agentModel->getLastSql());
                            if(!$rs){
                                $cardChargeOrderModel->rollback();
                                $repData['msg'] = '更新代理商收入失败';
                                $curl->send('onlineCardCharge', $repData);
                                return true;
                            }
                        }
                        
                        if($order['store_id'] > 0 && $storeAmount > 0){
                            $store = $storeModel->where(['store_id' => $order['store_id']])->field('total_amount, profit_amount, profit_online_card_amount, amount')->lock(true)->find();
                            
                            if(!empty($store)){
                                $storeUpdate = [
                                    'total_amount' => $consumeAmount + $store['total_amount']
                                ];
                                
                                if($storeAmount > 0){
                                    $storeUpdate['profit_amount'] = $storeAmount + $store['profit_amount'];
                                    $storeUpdate['profit_online_card_amount'] = $storeAmount + $store['profit_online_card_amount'];
                                    if($order['pay_to'] == 1){
                                        $storeUpdate['amount'] = $storeAmount + $store['amount'];
                                    }
                                    
                                    
                                    $rs = $storeFinanceModel->add(['store_id' => $order['store_id'], 'related_id' => $orderId, 'type' => 2, 'amount' => $storeAmount, 'add_time' => $time]);
                                    if(!$rs){
                                        $cardChargeOrderModel->rollback();
                                        $repData['msg'] = '加入门店收入记录失败';
                                        $curl->send('onlineCardCharge', $repData);
                                        return true;
                                    }
                                }
                                
                                $rs = $storeModel->modify(['store_id' => $order['store_id']], $storeUpdate);
                                if(!$rs){
                                    $cardChargeOrderModel->rollback();
                                    $repData['msg'] = '更新门店收入失败';
                                    $curl->send('onlineCardCharge', $repData);
                                    return true;
                                }
                            }
                        }
                    }
                    
                    $flatform = $platformModel->where(['id' => 1])->field('online_card_amount')->lock(true)->find();
                    $rs = $platformModel->modify(['id' => 1], ['online_card_amount' => $flatform['online_card_amount'] + $consumeAmount]);
                    if(!$rs){
                        $cardChargeOrderModel->rollback();
                        $repData['msg'] = '更新平台收入失败';
                        $curl->send('onlineCardCharge', $repData);
                        return true;
                    }
                    
                    $rs = $flatformFinanceLogModel->add(['related_id' => $orderId, 'type' => 2, 'amount' => $consumeAmount, 'add_time' => $time]);
                    if(!$rs){
                        $cardChargeOrderModel->rollback();
                        $repData['msg'] = '加入平台收入记录失败';
                        $curl->send('onlineCardCharge', $repData);
                        return true;
                    }
                }
                
                $repData['success'] = true;
                $repData['money'] = $card['amount'] * 100;
                
                $result = $curl->send('onlineCardCharge', $repData);
                if($result['success'] == true) {
                    $cardChargeOrderModel->commit();
                }else{
                    $cardChargeOrderModel->rollback();
                }
                
            } catch (\Exception $e) {
                $cardChargeOrderModel->rollback();
                $repData['msg'] = $e->getMessage();
                $curl->send('onlineCardCharge', $repData);
            }
            
            return true;
            
       });
        
        return successResult();
    }
}









